package com.example.casper.Experiment2024.fragment;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.example.casper.Experiment2024.R;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

@SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
public class GameViewFragment extends Fragment {

    private SurfaceView surfaceView;
    private TextView scoreTextView, timerTextView;
    private int score;
    private long startTime;
    private final Handler uiHandler = new Handler();
    private GameManager gameManager;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_game_view, container, false);

        surfaceView = rootView.findViewById(R.id.surfaceView);
        scoreTextView = rootView.findViewById(R.id.scoreTextView);
        timerTextView = rootView.findViewById(R.id.timeTextView);
        Button resetButton = rootView.findViewById(R.id.resetButton);

        resetButton.setOnClickListener(v -> resetGame());

        startTime = SystemClock.elapsedRealtime();
        score = 0;

        gameManager = new GameManager(surfaceView);
        surfaceView.setOnTouchListener(gameManager);

        uiHandler.postDelayed(this::updateUI, 1000);
        return rootView;
    }

    private void resetGame() {
        score = 0;
        startTime = SystemClock.elapsedRealtime();
        gameManager.reset();
        scoreTextView.setText("Score: 0");
    }

    private void updateUI() {
        long elapsed = (SystemClock.elapsedRealtime() - startTime) / 1000;
        timerTextView.setText("Running Time: " + elapsed + "s");
        uiHandler.postDelayed(this::updateUI, 1000);
    }

    private class GameManager implements SurfaceHolder.Callback, Runnable, View.OnTouchListener {

        private final SurfaceHolder surfaceHolder;
        private final Random random = new Random();
        private final List<Obstacle> obstacles = new LinkedList<>();
        private Thread gameThread;
        private boolean running;
        private Bitmap playerBitmap, obstacleBitmap;
        private int playerX, playerY;
        private int screenWidth, screenHeight;
        private int obstacleSpeed = 8;  // 初始炸弹速度
        private int obstacleGenerationRate = 5;  // 初始生成炸弹的概率

        private long startTime;  // 记录游戏开始的时间

        GameManager(SurfaceView surfaceView) {
            this.surfaceHolder = surfaceView.getHolder();
            surfaceHolder.addCallback(this);
            startTime = SystemClock.elapsedRealtime();  // 初始化开始时间
        }

        @Override
        public void surfaceCreated(@NonNull SurfaceHolder holder) {
            screenWidth = surfaceView.getWidth();
            screenHeight = surfaceView.getHeight();
            playerBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.boat), screenWidth / 6, screenHeight / 12, true);
            obstacleBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bomb), screenWidth / 15, screenWidth / 15, true);
            playerX = screenWidth / 2 - playerBitmap.getWidth() / 2;
            playerY = screenHeight - playerBitmap.getHeight() - 50;
            startGame();
        }

        @Override
        public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {}

        @Override
        public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
            stopGame();
        }

        private void startGame() {
            if (gameThread != null && gameThread.isAlive()) {
                return;
            }
            running = true;
            gameThread = new Thread(this);
            gameThread.start();
        }
        private void stopGame() {
            running = false;
        }
        void reset() {
            stopGame();
            obstacles.clear();
            playerX = screenWidth / 2 - playerBitmap.getWidth() / 2;
            playerY = screenHeight - playerBitmap.getHeight() - 50;
            score = 0;
            scoreTextView.setText("Score: 0");

            Canvas canvas = surfaceHolder.lockCanvas();
            if (canvas != null) {
//                canvas.drawColor(Color.MAGENTA);
                canvas.drawColor(Color.parseColor("#FFFACD"));  // 背景设置为橙色，十六进制颜色

                surfaceHolder.unlockCanvasAndPost(canvas);
            }
            startTime = SystemClock.elapsedRealtime();
            startGame();
        }
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            playerX = (int) event.getX() - playerBitmap.getWidth() / 2;
            if (playerX < 0) playerX = 0;
            if (playerX > screenWidth - playerBitmap.getWidth())
                playerX = screenWidth - playerBitmap.getWidth();
            return true;
        }
        @Override
        public void run() {
            while (running) {
                updateGame();
                drawGame();
                try {
                    Thread.sleep(16);
                } catch (InterruptedException ignored) {}
            }
        }
        private void updateGame() {
            long elapsed = (SystemClock.elapsedRealtime() - startTime) / 1000;
            if (elapsed > 0) {
                obstacleSpeed = (int) (10 + elapsed / 5);  // 每5秒炸弹速度加快10
                obstacleGenerationRate = (int) (5 + elapsed / 10);  // 每10秒生成更多炸弹
            }

            // 控制炸弹的生成概率
            if (random.nextInt(100) < obstacleGenerationRate) {
                int obstacleX = random.nextInt(screenWidth - obstacleBitmap.getWidth());
                obstacles.add(new Obstacle(obstacleX, -obstacleBitmap.getHeight()));
            }

            List<Obstacle> toRemove = new LinkedList<>();

            for (Obstacle obstacle : obstacles) {
                obstacle.update();
                if (obstacle.y > surfaceView.getHeight()) {  // 使用 SurfaceView 的高度
                    score++;
                    toRemove.add(obstacle);
                } else if (checkCollision(obstacle)) {
                    stopGame();
                    requireActivity().runOnUiThread(() -> scoreTextView.setText("Final Scores: " + score));
                    return;
                }
            }
            obstacles.removeAll(toRemove);
            requireActivity().runOnUiThread(() -> scoreTextView.setText("Score: " + score));
        }
        private boolean checkCollision(Obstacle obstacle) {
            return obstacle.x < playerX + playerBitmap.getWidth() &&
                    obstacle.x + obstacle.width > playerX &&
                    obstacle.y < playerY + playerBitmap.getHeight() &&
                    obstacle.y + obstacle.height > playerY;
        }
        private void drawGame() {
            Canvas canvas = surfaceHolder.lockCanvas();
            if (canvas != null) {
                try {
//                    canvas.drawColor(Color.MAGENTA);
                    canvas.drawColor(Color.parseColor("#FFFACD"));  // 背景设置为橙色，十六进制颜色
                    canvas.drawBitmap(playerBitmap, playerX, playerY, null);
                    for (Obstacle obstacle : obstacles) {
                        canvas.drawBitmap(obstacleBitmap, obstacle.x, obstacle.y, null);
                    }
                } finally {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
        }
        private class Obstacle {
            int x, y, width, height, speed;

            Obstacle(int x, int y) {
                this.x = x;
                this.y = y;
                this.width = obstacleBitmap.getWidth();
                this.height = obstacleBitmap.getHeight();
                this.speed = obstacleSpeed;
            }
            void update() {
                y += speed;
            }
        }
    }

}